#include "inc/system.h"
#include "inc/print.h"
#include "inc/math.h"

int video_buff;

int getpixel(int r, int g, int b)
{
  int val = 0;
  val += (r >> 3) << (5 + 6);
  val += (g >> 2) << (5);
  val += (b >> 3);
  return val;
}

//MaxIterations maxi = 256
//maxm=4
void f(int wid, int hei, double viswid, double vishei, double visx, double visy, int maxi, double maxm)
{
  short* buffAddr = (short*)video_buff;

	int i;
	int j;
	int index = 0;
	int clr;
	double ReaC;
	double ImaC;
	double dReaC;
	double dImaC;
	double ReaZ;
	double ImaZ;
	double ReaZ2;
	double ImaZ2;
	//int n;

	//n = 256 / maxi;

	dReaC = (viswid) / ((double)wid - 1);
	dImaC = (vishei) / ((double)hei - 1);

  int v = getpixel(0, 0, 255);
	for (j = 0; j < hei; j++)
	{
    short* addr;
		for (i = 0; i < wid; i++)
		{
      addr = buffAddr+i+(j<<10);
      *addr = v;//at 2Mbyte
		}
    flushCache(addr);
	}

	ReaC = visy;
  
  IOWR(MYTIMER, MYTIMER_32TOP, 0xFFFFFFFF);

	for (j = 0; j < hei; j++)
	{
    IOWR(MYTIMER, MYTIMER_32, 0);
		ReaC += dReaC;
		ImaC = visx;
		for (i = 0; i < wid; i++)
		{
			ImaC += dImaC;
			ReaZ = 0;
			ImaZ = 0;
			ReaZ2 = 0;
			ImaZ2 = 0;
			clr = 1;

			while (clr++ < maxi && ReaZ2 + ImaZ2 < maxm)
			{
				ReaZ2 = ReaZ * ReaZ;
				ImaZ2 = ImaZ * ImaZ;
				ImaZ = 2 * ImaZ * ReaZ + ImaC;
				ReaZ = ReaZ2 - ImaZ2 + ReaC;
			}
      
      short* addr = buffAddr+i+(j<<10);
      
      //*addr = getpixel(0, clr, 0);// * n    at 2Mbyte
      int v1 = 0;
      int v2 = clr;
      __asm__ __volatile__("setrgb %0,%1,%2,1":"=r"(v1):"r"(v1),"r"(v2));
      *addr = v1;

      flushCache(addr);
		}
    
    printInt(j);print(",");printInt(IORD(MYTIMER, MYTIMER_32));print(" \r\n");

	}
}
int videomemPos = 62*512;
//int videomemPos = 30*512;
int main()
{
  stdioInit(videomemPos);//30720=30Mbyte last 512k is stack
  video_buff = videomemPos*2048;

  print("start");
  f(256, 192 , 2, 2, -1, -1, 254, 4);
  while(1){
  }

  return 0;
  
}
